package br.com.teste.xml;

import br.com.hs.nfe.NotaFiscalHelper;
import br.com.hs.nfe.AppUtil;
import br.com.hs.nfe.NotaFiscalUtil;
import br.com.hs.nfe.certificado.exception.HSCertificadoException;
import br.com.hs.nfe.common.enumeration.*;
import br.com.hs.nfe.common.exception.*;
import br.com.hs.nfe.common.to.*;
import br.com.hs.nfe.common.util.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Ranlive Hrysyk
 */
public class GeracaoXML {

    public static final String DIRETORIO = "/home/ranlive/Documentos/";

    public static void main(String[] args) {
        //Cria o emitente
        System.out.println("Criando e registrando o emitente...");
        EmitenteTO emitenteTO = createEmitenteTO();
        AppUtil.registrarEmitenteTO(emitenteTO);

        //Obtém a nota
        System.out.println("Criando a nota fiscal...");
        NotaFiscalTO notaFiscalTO = createNotaFiscalTO();
        List<NotaFiscalTO> notas = new ArrayList<NotaFiscalTO>();
        notas.add(notaFiscalTO);

        try {
            System.out.println("Validando a nota...");
            NotaFiscalUtil.validarNotaFiscalTO(notas);

            if (notaFiscalTO.hasErrors()) {
                printError(notaFiscalTO);
                if (notaFiscalTO.hasValidationError()) {
                    System.out.println("-----------------------------------------");
                    printValidationError(notaFiscalTO);
                }
            } else {
                printMessages(notaFiscalTO);

                notas = NotaFiscalUtil.assinarXML(notas, GeracaoXML.createCertificadoTO());

                for (NotaFiscalTO nota : notas) {
                    if (notaFiscalTO.hasErrors()) {
                        printError(nota);
                    } else {
                        printMessages(nota);
//                    if (ExportacaoBusiness.exportarNotaFiscal(notaFiscalTO, ExtensaoArquivoEnum.XML, DIRETORIO, DocumentHelper.createNFeDocument(notaFiscalTO.getXmlString()).getNFe().getInfNFe().getId())) {
//                        System.out.println("XML exportado com sucesso!");
//                    } else {
//                        System.out.println("Erro na exportação!");
//                    }
                    }
                }
            }
        } catch (Exception ex) {
            Logger.getLogger(GeracaoXML.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Imprime os erros.
     */
    public static void printError(BaseTO baseTO) {
        for (String error : baseTO.getErrors()) {
            System.out.println(error);
        }
        baseTO.clearErrors();
    }

    /**
     * Imprime os erros de validação.
     */
    public static void printValidationError(BaseTO baseTO) {
        for (String error : baseTO.getValidationErrorList()) {
            System.out.println(error);
        }
        baseTO.clearValidationError();
    }

    /**
     * Imprime as mensagens.
     */
    public static void printMessages(BaseTO baseTO) {
        for (String message : baseTO.getMessages()) {
            System.out.println(message);
        }
        baseTO.clearMessages();
    }

    /**
     * NotaFiscalTO
     */
    public static NotaFiscalTO createNotaFiscalTO() {
        try {
            //Cria uma nova nota fiscal
            NotaFiscalTO notaFiscalTO = new NotaFiscalTO();

            //Atribui os dados da nota fiscal
            //notaFiscalTO.setVersao(AppConfig.getInstance().getVersaoSchema());
            notaFiscalTO.setNaturezaOperacao("VENDA");
            notaFiscalTO.setFormaPagamento(FormaPagamentoEnum.A_VISTA);
            //notaFiscalTO.setModelo("55");
            notaFiscalTO.setSerie(String.valueOf(Integer.parseInt("1")));
            notaFiscalTO.setNumero("1");
            notaFiscalTO.setDataEmissao(new Date());
            notaFiscalTO.setDataSaidaEntrada(new Date());
            notaFiscalTO.setHoraSaidaEntrada(new Date());
            notaFiscalTO.setTipoOperacao(TipoOperacaoEnum.SAIDA);
            notaFiscalTO.setCodigoMunicipioFG("5107909");
            notaFiscalTO.setTipoImpressao(TipoImpressaoEnum.RETRATO);
            //notaFiscalTO.setTipoEmissao(TipoEmissaoEnum.NORMAL);
            //notaFiscalTO.setCodigoNumericoChaveAcesso(ChaveAcessoHelper.gerarCodigoNumerico(notaFiscalTO.getXmlString()));
            //notaFiscalTO.setTipoAmbiente(TipoAmbienteEnum.HOMOLOGACAO);
            //notaFiscalTO.setFinalidadeEmissao(FinalidadeEmissaoEnum.NFE_NORMAL);
            //notaFiscalTO.setProcessoEmissao(ProcessoEmissaoEnum.NFE_APLICATIVO_CONTRIBUINTE);
            //notaFiscalTO.setVersaoProcesso(AppConfig.getInstance().getVersaoAplicativo());


            //Atribui o cliente
            notaFiscalTO.setClienteTO(createClienteTO());

            //Atribui os produtos
            List<ProdutoNotaTO> listaProdutos = new ArrayList<ProdutoNotaTO>();
            listaProdutos.add(createProdutoNotaTO());
            notaFiscalTO.setListaProdutos(listaProdutos);

            //Atribui os dados do transporte
            notaFiscalTO.setTransporteTO(createTransporteTO());

            //Atribui as informações adicionais da NF-e
            notaFiscalTO.setInfoTO(createInfoTO());

            //Calcula os valores dos impostos
            NotaFiscalHelper notaFiscalHelper = new NotaFiscalHelper();
            notaFiscalHelper.calculateImpostos(notaFiscalTO);

            //Calcula o total da nota
            notaFiscalHelper.calculateTotalNotaFiscal(notaFiscalTO);

            //Atualiza os dados do XML da NF-e
            DocumentHelper.updateXml(notaFiscalTO);
            return notaFiscalTO;
        } catch (HSCommonException ex) {
            Logger.getLogger(GeracaoXML.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    /**
     * EmitenteTO.
     */
    public static EmitenteTO createEmitenteTO() {
        EmitenteTO emit = new EmitenteTO();
        emit.setCNPJ("73967085000317");
        emit.setXNome("UNIMED NORTE DO MATO GROSSO COOPERATIVA DE TRABALHO MEDICO");
        emit.setXFant("FARMACIA UNIMED SINOP");
        emit.setEnderEmit(createEnderecoTO());
        emit.setIE("132090171");
        emit.setCRT("3");
        return emit;
    }

    /**
     * ClienteTO Homologação.
     */
    public static ClienteTO createClienteTO() {
        ClienteTO cli = new ClienteTO();
        cli.setCNPJ("99999999000191");
        cli.setXNome("NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL");
        cli.setIE("");
        cli.setEnderDest(createEnderecoTO());
        cli.setEmail("ranlive@unimed279.com.br");
        return cli;
    }

    /**
     * LocalTO.
     */
    public static LocalTO createLocalTO() {
        LocalTO localTO = new LocalTO();
        localTO.setCNPJ(createClienteTO().getCNPJ());
        localTO.setEnderecoTO(createEnderecoTO());
        return localTO;
    }

    /**
     * EnderecoTO.
     */
    public static EnderecoTO createEnderecoTO() {
        EnderecoTO end = new EnderecoTO();
        end.setXLgr("AV DOS JACARANDAS");
        end.setNro("3219");
        end.setXCpl("EDF CECILIA");
        end.setXBairro("CENTRO");
        end.setCMun("5107909");
        end.setXMun("Sinop");
        end.setUF("MT");
        end.setCEP("78550246");
        end.setCPais("1058");
        end.setXPais("BRASIL");
        end.setFone("6635117120");
        return end;
    }

    /**
     * ProdutoNotaTO.
     */
    public static ProdutoNotaTO createProdutoNotaTO() {
        ProdutoNotaTO produtoNotaTO = new ProdutoNotaTO();
        produtoNotaTO.setProduto(createProdutoTO());
        produtoNotaTO.setICMS(createIcmsTO());
        produtoNotaTO.setPIS(createPisTO());
        produtoNotaTO.setCOFINS(createCofinsTO());
        return produtoNotaTO;
    }

    /**
     * ProdutoTO.
     */
    public static ProdutoTO createProdutoTO() {
        ProdutoTO prod = new ProdutoTO();
        prod.setCProd("3544");
        prod.setCEAN("");
        prod.setXProd("CICLOPLEGICO SOL FR 5ML");
        prod.setNCM("30049099");
        prod.setCFOP("5929");
        prod.setUCom("CX");
        prod.setQCom(new BigDecimal("1"));
        prod.setVUnCom(new BigDecimal("7.61"));
        prod.setVProd(new BigDecimal("7.61"));
        prod.setCEANTrib("");
        prod.setUTrib("CX");
        prod.setQTrib(new BigDecimal("1"));
        prod.setVUnTrib(new BigDecimal("7.61"));
        prod.setVDesc(new BigDecimal("1.14"));
        prod.setIndTot("1");
        prod.setMedArray(new MedicamentoTO[]{createMedicamentoTO()});
        return prod;
    }

    /**
     * MedicamentoTO.
     */
    public static MedicamentoTO createMedicamentoTO() {
        MedicamentoTO med = new MedicamentoTO();
        med.setNLote("30591");
        med.setQLote(new BigDecimal("1"));
        med.setDFab(DateHelper.getDate("30/10/2011"));
        med.setDVal(DateHelper.getDate("30/10/2012"));
        med.setVPMC(new BigDecimal("7.61"));
        return med;
    }

    /**
     * IcmsTO.
     */
    public static IcmsTO createIcmsTO() {
        IcmsTO icms = new IcmsTO();
        icms.setOrigEnum(OrigEnum.NACIONAL);
        icms.setCSTEnum(CSTEnum.X_40);
        return icms;
    }

    /**
     * PisTO.
     */
    public static PisTO createPisTO() {
        PisTO pis = new PisTO();
        pis.setCSTEnum(PISEnum.PIS_07);
        return pis;
    }

    /**
     * CofinsTO.
     */
    public static CofinsTO createCofinsTO() {
        CofinsTO cofins = new CofinsTO();
        cofins.setCSTEnum(COFINSEnum.COFINS_07);
        return cofins;
    }

    /**
     * TransporteTO.
     */
    public static TransporteTO createTransporteTO() {
        TransporteTO transp = new TransporteTO();
        transp.setModalidadeFrete(ModalidadeFreteEnum.POR_CONTA_EMITENTE);
        return transp;
    }

    /**
     * InfoTO.
     */
    public static InfoTO createInfoTO() {
        InfoTO info = new InfoTO();
        info.setInfAdFisco(""
                + "Informacoes Adicionais de Interesse do Fisco- Superintendencia de Defesa do Consumidor "
                + "PROCON-MT Av Historia Rubens de Mendonca, 917-Bairro Arraes Edif. Executive Center cep 78008-000 "
                + "Cuiaba-MT Tel Reclamacao 151. "
                + "VENDA REF CF000001 CLIENTE " + createClienteTO().getXNome());
        return info;
    }

    /**
     * CertificadoTO.
     */
    public static CertificadoTO createCertificadoTO() throws HSCertificadoException {
        return NotaFiscalUtil.createCertificadoTO("/home/ranlive/Documentos/Certificados/CertificadoDigital.pfx", "serasa12");
    }
}
